﻿using Google.Protobuf.WellKnownTypes;
using HPSocket;
using IntelligentGateway.Data;
using IntelligentGateway.Model;
using IntelligentGateway.Model.Panel;
using IntelligentGateway.Model.Platform;
using IntelligentGateway.Services.Panel;
using IntelligentGateway.Tools;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Org.BouncyCastle.Asn1.Ocsp;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Net;
using System.Resources;
using System.Text;
using System.Threading.Tasks;

namespace IntelligentGateway.Services
{
    public class IntelligentGatewayServices
    {
        #region Websocket
        public static bool StartIGWebSocketClient()
        {
            string IpAddress = GlobalVariables.IGWebSocketServerSetting.IPAddress;
            string Port = GlobalVariables.IGWebSocketServerSetting.Port;
            if (string.IsNullOrEmpty(IpAddress))
            {
                return true;
            }
            string host = string.Empty;
            if(string.IsNullOrEmpty(Port))
            {
                host = IpAddress;
            }
            else
            {
                host = $"{IpAddress}:{ Port}";
            }
           
            GlobalVariables.IntelligentWebSocketClient = new WebSocketClient(host);
            GlobalVariables.IntelligentWebSocketClient.OnWSText += IntelligentWebSocketClient_OnWSText;
            bool result = GlobalVariables.IntelligentWebSocketClient.Start();
            return result;
        }
        public static bool StartTPWebSocketServer()
        {
            string IpAddress = GlobalVariables.TPWebSocketServerSetting.IPAddress;
            string Port = GlobalVariables.TPWebSocketServerSetting.Port;
            if (string.IsNullOrEmpty(IpAddress))
            {
                return true;
            }
            string host = string.Empty;
            if (string.IsNullOrEmpty(Port))
            {
                host = IpAddress;
            }
            else
            {
                host = $"{IpAddress}:{Port}";
            }

            GlobalVariables.IntelligentWebSocketServer = new TPWebsocketServer(host);           
            bool result = GlobalVariables.IntelligentWebSocketServer.Start();
            return result;
        }
        private static void IntelligentWebSocketClient_OnWSText(HPSocket.IWebSocketAgent sender, IntPtr connId, byte[] data)
        {
            if (data.Length > 0)
            {
                WSMessageProcess.ProcessClientSendMessage(sender, connId, data);
            }
        }
        public static async Task<WebSocketResponse> queryInfo(string JsonInfo)
        {
            WebSocketResponse response = new WebSocketResponse();
            try
            {
                WebSocketRequest request = JsonConvert.DeserializeObject<WebSocketRequest>(JsonInfo);

                if (request != null)
                {
                    DeviceInfoDA deviceInfoDA = new DeviceInfoDA();
                    MasterDeviceInfo mInfo = deviceInfoDA.GetMasterDeviceInfo();
                    List<SubDeviceInfo> sInfo = deviceInfoDA.GetSubDeviceInfo(mInfo.ID);
                    List<Model.Platform.DeviceInfo> deviceInfos = new List<Model.Platform.DeviceInfo>();
                    Model.Platform.DeviceInfo mdevice = new Model.Platform.DeviceInfo();
                    mdevice.stateIntervalTime = 10;
                    mdevice.deviceID = mInfo.NO.ToString();
                    mdevice.deviceIP = mInfo.DeviceIP;
                    mdevice.devDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    mdevice.deviceState = 0;
                    mdevice.errNO = 0;
                    mdevice.liftMode = 1;
                    deviceInfos.Add(mdevice);
                    foreach (var st in sInfo)
                    {
                        Model.Platform.DeviceInfo device = new Model.Platform.DeviceInfo();
                        device.stateIntervalTime = 10;
                        device.deviceID = st.NO.ToString();
                        device.deviceIP =st.DeviceIP;
                        device.devDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                        device.deviceState = 0;
                        device.errNO = 0;
                        device.liftMode = 1;
                        deviceInfos.Add(device);
                    }
                    response.code = 0;
                    response.msg = "success";
                    response.data = deviceInfos;
#if TEST
                    //List<Model.Platform.DeviceInfo> lst = new List<Model.Platform.DeviceInfo>();
                    //Model.Platform.DeviceInfo info = new Model.Platform.DeviceInfo { stateIntervalTime = 60, deviceID = "10000002",
                    //    deviceIP = "192.168.1.100", devDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), deviceState = 1, errNO = 0, liftMode = 0 };
                    //lst.Add(info);
                    //Model.Platform.DeviceInfo info1 = new Model.Platform.DeviceInfo
                    //{
                    //    stateIntervalTime = 10,
                    //    deviceID = "10000001",
                    //    deviceIP = "192.168.1.101",
                    //    devDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                    //    deviceState = 0,
                    //    errNO = 1,
                    //    liftMode = 1
                    //};
                    //lst.Add(info1);
                    //response.code = 0;
                    //response.msg = "success";
                    //response.data = lst;
#endif
                }
                else
                {
                    response.code = 1;
                    response.msg = "无数据!";
                }                

            }
            catch (Exception ex)
            {
                response.code = 2;
                response.msg = "json数据格式有问题!";
            }
            return response;
        }
        public static async Task<WebSocketResponse> setParameter(string JsonInfo)
        {
            WebSocketResponse response = new WebSocketResponse();
            try
            {
                WebSocketRequest request = JsonConvert.DeserializeObject<WebSocketRequest>(JsonInfo);
                JToken token = (JToken)request.data;
                List<Model.Platform.DeviceInfo> data = token.ToObject<List<Model.Platform.DeviceInfo>>();

                if (request != null && data != null)
                {
#if TEST
                    List<setParameterResponse> lst = new List<setParameterResponse>();
                    foreach (Model.Platform.DeviceInfo info in data)
                    {
                        setParameterResponse setParameterResponse = new setParameterResponse()
                        {
                            errNO = 0,
                            deviceID = info.deviceID
                        };
                        lst.Add(setParameterResponse);
                    }
                    response.code = 0;
                    response.msg = "success";
                    response.data = lst;
#endif
                }
                else
                {
                    response.code = 1;
                    response.msg = "无数据!";
                }

            }
            catch (Exception ex)
            {
                response.code = 2;
                response.msg = "json格式有问题!";
            }
            return response;
        }
        public static async Task<WebSocketResponse> savePerson(string JsonInfo)
        {
            WebSocketResponse response = new WebSocketResponse();
            try
            {
                WebSocketRequest request = JsonConvert.DeserializeObject<WebSocketRequest>(JsonInfo);
                JToken token = (JToken)request.data;
                savePersonRequest data = token.ToObject<savePersonRequest>();

                if (request != null && data != null)
                {

                    List<savePersonResponse> lst = new List<savePersonResponse>();
                    DeviceInfoDA da = new DeviceInfoDA();
                    SyncDataServices syncDataServices = new SyncDataServices();
                    PersonInfoDA personInfoDA = new PersonInfoDA();
                    foreach (var device in data.deviceInfos)
                    {
                        string deviceid = device.deviceID;                       
                        string PanelIP = da.GetPanelIP(deviceid);
                        if (string.IsNullOrEmpty(PanelIP))
                        {
                            response.code = 1;
                            response.msg = $"{device.deviceID}找不到面板IP!";
                            return response;
                        }                            
                        foreach (var person in data.personInfos)
                        {
                            string personid = person.personID;
                            savePersonResponse savePersonResponse = new savePersonResponse();
                            if (!string.IsNullOrEmpty(person.personPhoto))
                            {
                                SavePersonPicture picture = new SavePersonPicture();
                                picture.@params = new PictureInfo();
                                picture.@params.PersonID = person.personID;
                                picture.@params.Picture = person.personPhoto;
                                picture.Token = GlobalVariables.Token;
                                PanelResponseMessage picturemessage = await syncDataServices.SavePersonPicture(picture, PanelIP);
                                savePersonResponse.errNO = picturemessage.result;
                                savePersonResponse.personID = person.personID;
                                savePersonResponse.deviceID = device.deviceID;                                                                
                            }
                            if (savePersonResponse.errNO == 0)
                            {
                                SavePerson savePerson = new SavePerson();
                                savePerson.@params = new Model.Panel.PersonInfo();
                                savePerson.@params.ICCardID = person.cardNO;
                                savePerson.@params.ExpireTime = (long)(DateTime.Parse(person.endTime).ToUniversalTime() - new DateTime(1970, 1, 1)).TotalSeconds;
                                savePerson.@params.PersonID = person.personID;
                                savePerson.@params.EffectiveTime = (long)(DateTime.Parse(person.startTime).ToUniversalTime() - new DateTime(1970, 1, 1)).TotalSeconds;
                                savePerson.@params.Authority = 1;
                                savePerson.@params.DepartID = 1;
                                savePerson.@params.Gender = person.sex;
                                savePerson.@params.PersonName = person.personName;
                                savePerson.Token = GlobalVariables.Token;
                                PanelResponseMessage message = await syncDataServices.SavePerson(savePerson, PanelIP);
                                if (message.result == 0)
                                {
                                    bool success = personInfoDA.InsertUpdate(person);
                                    if (!success)
                                    {
                                        response.code = 2;
                                        response.msg = "插入员工数据错误!";
                                        savePersonResponse.errNO = 1;
                                    }
                                }
                                else
                                {
                                    response.code = 3;
                                    response.msg = "下发员工资料失败!" ;
                                    savePersonResponse.errNO = message.result;
                                }
                            }
                            else
                            {
                                response.code = 4;
                                response.msg = "下发图片错误!";                                
                            }
                            lst.Add(savePersonResponse);
                        }
                    }                    
                    response.msg = string.IsNullOrEmpty(response.msg)?"success":response.msg;
                    response.data = lst;
                }
                else
                {
                    response.code = 1;
                    response.msg = "无数据";                    
                }

            }
            catch (Exception ex)
            {
                response.code = 2;
                response.msg = "json格式有问题!";
            }
            return response;
        }
        public static async Task<WebSocketResponse> delPerson(string JsonInfo)
        {
            WebSocketResponse response = new WebSocketResponse();
            try
            {
                WebSocketRequest request = JsonConvert.DeserializeObject<WebSocketRequest>(JsonInfo);
                JToken token = (JToken)request.data;
                delPersonRequest data = token.ToObject<delPersonRequest>();
                if (request != null && data != null)
                {
                    List<savePersonResponse> lst = new List<savePersonResponse>();
                    DeviceInfoDA da = new DeviceInfoDA();
                    SyncDataServices syncDataServices = new SyncDataServices();
                    PersonInfoDA personInfoDA = new PersonInfoDA();
                    foreach (var device in data.deviceInfos)
                    {
                        string deviceid = device.deviceID;
                        string PanelIP = da.GetPanelIP(deviceid);
                        if (string.IsNullOrEmpty(PanelIP))
                        {
                            response.code = 1;
                            response.msg = $"{device.deviceID}找不到面板IP!";
                            return response;
                        }
                        foreach (var person in data.personInfos)
                        {
                            string personid = person.personID;
                            SavePerson savePerson = new SavePerson()
                            {
                                @params = new Model.Panel.PersonInfo { PersonID = personid },
                                Token = GlobalVariables.Token
                            };
                            PanelResponseMessage message = await syncDataServices.DeletePerson(savePerson, PanelIP);
                            savePersonResponse savePersonResponse = new savePersonResponse()
                            {
                                errNO = message.result,
                                personID = person.personID,
                                deviceID = device.deviceID
                            };
                            //if (message.result == 0) 数据可能也在其他设备上问题，暂时不删除.
                            //{
                            //    bool success = personInfoDA.DeletePerson(personid);
                            //    if(!success)
                            //    {
                            //        response.code = 2;
                            //        response.msg = "删除员工数据错误!";
                            //        savePersonResponse.errNO = 1;
                            //    }
                            //}                            
                            lst.Add(savePersonResponse);
                        }
                    }
                    response.code = 0;
                    response.msg = "success";
                    response.data = lst;
                }
                else
                {
                    response.code = 1;
                    response.msg = "无数据!";
                }
            }
            catch (Exception ex)
            {
                response.code = 2;
                response.msg = "json格式有问题!";
            }
            return response;
        }
        public static async Task<WebSocketResponse> clearPerson(string JsonInfo)
        {
            WebSocketResponse response = new WebSocketResponse();
            try
            {
                WebSocketRequest request = JsonConvert.DeserializeObject<WebSocketRequest>(JsonInfo);
                JToken token = (JToken)request.data;
                List<deviceInfoRequest> data = token.ToObject<List<deviceInfoRequest>>();

                if (request != null && data != null)
                {
                    List<savePersonResponse> lst = new List<savePersonResponse>();
                    DeviceInfoDA da = new DeviceInfoDA();
                    SyncDataServices syncDataServices = new SyncDataServices();
                    PersonInfoDA personInfoDA = new PersonInfoDA();
                    foreach (var device in data)
                    {
                        string deviceid = device.deviceID;
                        string PanelIP = da.GetPanelIP(deviceid);
                        List<Model.Platform.PersonInfo> infos = personInfoDA.GetAllPerson();
                        foreach (var person in infos)
                        {
                            string personid = person.personID;
                            SavePerson savePerson = new SavePerson()
                            {
                                @params = new Model.Panel.PersonInfo { PersonID = personid },
                                Token = GlobalVariables.Token
                            };
                            PanelResponseMessage message = await syncDataServices.DeletePerson(savePerson, PanelIP);
                            savePersonResponse savePersonResponse = new savePersonResponse()
                            {
                                errNO = message.result,
                                deviceID = device.deviceID
                            };
                            lst.Add(savePersonResponse);
                        }
                    }                    
                    response.code = 0;
                    response.msg = "success";
                    response.data = lst;
                }
                else
                {
                    response.code = 1;
                    response.msg = "无数据!";
                }

            }

            catch (Exception e)
            {
                response.code = 2;
                response.msg = "json数据格式问题!";
            }
            return response;
        }
        public static async Task<WebSocketResponse> keepDoor(string JsonInfo)
        {
            WebSocketResponse response = new WebSocketResponse();
            try
            {
                WebSocketRequest request = JsonConvert.DeserializeObject<WebSocketRequest>(JsonInfo);
                JToken token = (JToken)request.data;
                keepDoorRequest data = token.ToObject<keepDoorRequest>();
                
                if (request != null && data != null)
                {
                    SignalPointDA dA = new SignalPointDA();
                    SignalPoint signalPoint = dA.GetSignalPointData("开门");
                    bool success = false;
                    if (data.keepOpenDoor==1)
                         success = IGTCPServerMessageProcess.ProcessKeepOpenDoor(signalPoint);
                    else
                        success = IGTCPServerMessageProcess.ProcessCancelOpenDoor(signalPoint);
                    if (success)
                    {
                        response.code = 0;
                        response.msg = "success";
                    }
                    else
                    {
                        response.code = 1;
                        response.msg = "发送开门保持信号错误!";
                    }
                }
            }
            catch (Exception ex)
            {
                response.code = 1;
                response.msg = "json格式不对!";
            }       
            return response;
        }
        public static async Task<WebSocketResponse> carCall(string JsonInfo)
        {
            WebSocketResponse response = new WebSocketResponse();
            try
            {
                WebSocketRequest request = JsonConvert.DeserializeObject<WebSocketRequest>(JsonInfo);
                JToken token = (JToken)request.data;
                carCallRequest data = token.ToObject<carCallRequest>();
                if (request != null && data != null)
                {
                    SignalPointDA da =new SignalPointDA();
                    SignalPoint point =  da.GetSignalPointData(data.desDoor, 0,false);
                    bool success = IGTCPServerMessageProcess.ProcessInCall(point);
                    if (success)
                    {
                        response.code = 0;
                        response.msg = "success";
                    }
                    else
                    {
                        response.code = 1;
                        response.msg = "发送内呼出错!";
                    }
                    
                }
                else
                {
                    response.code = 1;
                    response.msg = "无数据!";
                }
            }
            catch (Exception ex)
            {
                response.code = 2;
                response.msg = "json数据有问题!";
            }
            return response;
        }
        public static async Task<WebSocketResponse> devStateUpdate(string JsonInfo)//第三方调用回来数据，只需记录
        {
            return null;
        }
        public static bool eventRecord(string PanelIP,PushRecord pushRecord)
        {
            WebSocketRequest request = new WebSocketRequest();
            eventRecordRequest eventRecordRequest = new eventRecordRequest();
            PanelDeviceInfoDA deviceInfoDA = new PanelDeviceInfoDA();
            string deviceID = deviceInfoDA.GetDeviceIDFromPanel(PanelIP);
            if(string.IsNullOrEmpty(deviceID)) return false;
            eventRecordRequest.deviceID = deviceID;
            eventRecordRequest.recordTime = UTools.ConvertTimestampToDate(pushRecord.RecordTime).ToString("yyyy-MM-dd HH:mm:ss");
            eventRecordRequest.personID = pushRecord.PersonID;
            eventRecordRequest.verifyMode = pushRecord.RecordType;
            eventRecordRequest.verifyDeviceID = pushRecord.DeviceID;
            eventRecordRequest.capturePic = pushRecord.RecordPicture;
            request.req_id = UTools.GetCredNumber();
            request.method = "eventRecord";
            request.data = eventRecordRequest;
            string result = JsonConvert.SerializeObject(request);
#if DEBUG
            Log.Debug($"eventRecord:{PanelIP}:{result}");
#endif
            byte[] sendData = System.Text.Encoding.UTF8.GetBytes(result);
            bool success = GlobalVariables.IntelligentWebSocketClient.SendData(sendData);
            return success;
        }
        public static WebSocketResponse liftStatus(string JsonInfo)
        {
            return null;
        }
        public static WebSocketResponse getDateTime(string JsonInfo)
        {
            WebSocketRequest request = JsonConvert.DeserializeObject<WebSocketRequest>(JsonInfo);
            JToken token = (JToken)request.data;
            getDateTimeResponse data = token.ToObject<getDateTimeResponse>();           
            return null;
        }
        public static void sendDevStateUpdate(string IPAddress,int DeviceState)
        {
            WebSocketRequest request = new WebSocketRequest();
            devStateUpdateRequest devStateUpdateRequest = new devStateUpdateRequest();
            DeviceInfoDA deviceInfoDA = new DeviceInfoDA();
            string devID = deviceInfoDA.GetDeviceID(IPAddress);
            devStateUpdateRequest.deviceID = devID;
            devStateUpdateRequest.deviceState = DeviceState;
            devStateUpdateRequest.deviceIP = IPAddress;
            List<devStateUpdateRequest> lst = new List<devStateUpdateRequest>();
            lst.Add(devStateUpdateRequest);
            request.req_id = UTools.GetCredNumber();
            request.method = "devStateUpdate";
            request.data = lst;
            string result = JsonConvert.SerializeObject(request);
            byte[] sendData = System.Text.Encoding.UTF8.GetBytes(result);
            GlobalVariables.IntelligentWebSocketClient.SendData(sendData);
        }        
        #endregion
        #region SerialPort
        public static bool StartSerialPort()
        {
            string strPortName = GlobalVariables.IGSerialPortSetting.PortName;
            string strBaudRate = GlobalVariables.IGSerialPortSetting.BaudRate;
            string strDataBits = GlobalVariables.IGSerialPortSetting.DataBits;
            string strParity = GlobalVariables.IGSerialPortSetting.Parity;
            string strStopBits = GlobalVariables.IGSerialPortSetting.StopBits;            
            GlobalVariables.SerialPortServer = new SerialPortServer(strPortName, strBaudRate, strDataBits, strParity,  strStopBits);
            GlobalVariables.SerialPortServer.SerialPort.DataReceived += SerialPort_DataReceived;
            bool result = GlobalVariables.SerialPortServer.Open();
            return result;
        }

        private static void SerialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(50);
            SerialPort sp = (SerialPort)sender;
            int count = sp.BytesToRead;
            if (count <= 0) return;
            byte[] data = new byte[count];
            sp.Read(data, 0, data.Length);            
#if DEBUG
            string strDebug = UTools.ToHexs(data, " ");
            Log.Debug("seriralport recevice data:"+strDebug);
#endif
            SerialMCMessageProcess.ProcessSerialData(data);
        }
        #endregion
        #region IGTCPClient
        //public static bool StartIGTCPClient()
        //{
        //    string IpAddress = AppSettingsTools.GetContent("IGTCPServer", "IPAddress");
        //    string Port = AppSettingsTools.GetContent("IGTCPServer", "Port");
        //    if (string.IsNullOrEmpty(IpAddress))
        //    {
        //        return true;
        //    }           
        //    GlobalVariables.IGTCPClient = new IGTCPClient(IpAddress, ushort.Parse(Port));           
        //    bool result = GlobalVariables.IGTCPClient.Start();
        //    return result;
        //}
        public static bool StartIGTCPServer()
        {
            string IpAddress = GlobalVariables.IGTCPServerSetting.IPAddress;
            string Port = GlobalVariables.IGTCPServerSetting.Port;
            if (string.IsNullOrEmpty(IpAddress))
            {
                return true;
            }
            GlobalVariables.IGTCPServer = new IGTCPServer(IpAddress, ushort.Parse(Port));
            bool result = GlobalVariables.IGTCPServer.Start();
            return result;
        }
        public static bool StartHeartBeat()
        {
            PanelDeviceInfoServices.startCheckHeartBeat();
            return true;
        }

        public static bool StartSignalPoint()
        {
            SignalPointServices.startCheckSignalPoint();
            return true;
        }
        #endregion

    }
}
